OS_ARCH := X86

CC := gcc
AS := as
LD := ld
LDFILE := linker.ld
O := -O0
W := -Wall -Wextra
CFLAGS := $(O) $(W) -ffreestanding -nostartfiles -m32 -mgeneral-regs-only
LDFLAGS := -nostdlib -m elf_i386
# -fPIE -no-pie -std=gnu99
KERNEL_DIR := kernel
BUILD_DIR := build
OBJ_DIR := $(BUILD_DIR)/obj
BIN_DIR := $(BUILD_DIR)/bin
ISO_DIR := $(BUILD_DIR)/iso
ISO_BOOT_DIR := $(ISO_DIR)/boot
ISO_GRUB_DIR := $(ISO_BOOT_DIR)/grub

INCLUDES_DIR := includes
INCLUDES := $(patsubst %, -I%, $(INCLUDES_DIR))

OS_NAME = lkhos
OS_BIN = $(OS_NAME).bin
OS_ISO = $(OS_NAME).iso

SRC_FILES := $(shell find -name "*.[cS]")
SRC := $(patsubst ./%, $(OBJ_DIR)/%.o, $(SRC_FILES))

C_FILES := $(filter %.c,$(SRC_FILES))
DIRS = $(sort $(dir $(C_FILES)))


$(OBJ_DIR):
	@mkdir -p $(OBJ_DIR)

$(BIN_DIR):
	@mkdir -p $(BIN_DIR)

$(ISO_DIR):
	@mkdir -p $(ISO_DIR)
	@mkdir -p $(ISO_BOOT_DIR)
	@mkdir -p $(ISO_GRUB_DIR)


# $(DIRS)/%.c.o:
# 	@echo $@
# 	@mkdir -p $(BUILD_DIR)/$@
# 	$(CC) -c $(filter %$(@F).c,$(SRC_FILES)) -o $(BUILD_DIR)/$@/$(@F).c.o

$(OBJ_DIR)/%.S.o: %.S
	@mkdir -p $(@D)
	$(CC) -m32 -c $< -o $@

$(OBJ_DIR)/%.c.o: %.c
	@mkdir -p $(@D)
	$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS)

$(BIN_DIR)/$(OS_BIN): $(OBJ_DIR) $(BIN_DIR) $(SRC)
	$(LD) -T $(LDFILE) -o $(BIN_DIR)/$(OS_BIN) $(SRC) $(LDFLAGS)

$(BUILD_DIR)/$(OS_ISO): $(ISO_DIR) $(BIN_DIR)/$(OS_BIN) GRUB_TEMPLATE
	@bash config-grub.sh $(OS_NAME) > $(ISO_GRUB_DIR)/grub.cfg
	@cp $(BIN_DIR)/$(OS_BIN) $(ISO_BOOT_DIR)
	@grub-mkrescue -o $(BUILD_DIR)/$(OS_ISO) $(ISO_DIR)

all: clean $(BUILD_DIR)/$(OS_ISO)

.PHONY: run clean debug

run: $(BUILD_DIR)/$(OS_ISO)
	@qemu-system-i386 -cdrom $(BUILD_DIR)/$(OS_ISO)

clean:
	@rm -rf $(BUILD_DIR)

makedebug:
	@echo $(SRC_FILES)
	@echo $(INCLUDES)
	@echo $(DIRS)

CFLAGS += -g

debug-bochs: debug all
	@bochs -q -f bochs.cfg